interface JsonSchemaRoot {
  $schema: string;
  title: string;
  description?: string;
}

export type JsonSchema = ObjectFieldSchemaSection & JsonSchemaRoot;


export interface IFieldSchemaSection {
  type: SchemaSectionType;
  default?: any;
  title?: string;
  // 
  required?: string[],
}

type SchemaSectionType = "string" | "boolean" | "integer" | "number" | "object" | "array" | "enum";

export interface StringFieldSchemaSection extends IFieldSchemaSection {
  type: 'string';
  default?: string;
  minLength?: number;
  maxLength?: number;
  pattern?: string;
  format?: StringFiedFormat;
  enum?: string[];
}

export type StringFiedFormat = "color" | "date" | "tel" | "date-time" | "time" | "email" | "hostname" | "ipv4" | "ipv6" | "uri" | "uuid";

export interface IntegerFieldSchemaSection extends IFieldSchemaSection {
  type: 'integer';
  default?: number;
  minimum?: number;
  maximum?: number;
}

export interface NumberFieldSchemaSection extends IFieldSchemaSection {
  type: 'number';
  default?: number;
  minimum?: number;
  maximum?: number;
}

export interface BooleanFieldSchemaSection extends IFieldSchemaSection {
  type: 'boolean';
  default?: boolean;
}

export interface ArrayFieldSchemaSection extends IFieldSchemaSection {
  type: "array";
  default?: [];
  items: FieldSchemaSection | { anyOf: FieldSchemaSection[]; };
}

export interface ObjectFieldSchemaSection extends IFieldSchemaSection {
  type: "object";
  default?: any;
  properties?: { [key: string]: FieldSchemaSection; },
  required?: string[],
}

export type FieldSchemaSection = ControlFieldSchemaSection
  | ArrayFieldSchemaSection
  | ObjectFieldSchemaSection;

export type ControlFieldSchemaSection = StringFieldSchemaSection
  | BooleanFieldSchemaSection
  | IntegerFieldSchemaSection
  | NumberFieldSchemaSection;